package stack_queue.queue.impl;

import stack_queue.queue.Queue;

public class LoopQueue implements Queue {
    private int[] data;
    // 有效元素个数(仅用front 和 tail来计算有效元素个数)
    private int size;
    // 指向队首元素下标
    private int front;
    // 指向队尾元素的下一个位置下标
    private int tail;

    public LoopQueue(int k) {
        data = new int[k + 1];
    }

    @Override
    public void offer(int value) {
        // 判断队列是否已满
        if (isFull()) {
            // 此时队列已满
            System.err.println("queue is full!");
            return;
        }
        data[tail] = value;
        tail = (tail + 1) % data.length;
        size ++;
    }

    @Override
    public int poll() {
        // 判断队列是否为空
        if (isEmpty()) {
            System.err.println("queue is empty!");
            return -1;
        }
        int value = data[front];
        front = (front + 1) % data.length;
        size --;
        return value;
    }

    @Override
    public int peek() {
        if (isEmpty()) {
            System.err.println("queue is empty!");
            return -1;
        }
        return data[front];
    }

    // 如何查看队尾元素?
    public int getTail() {
        if (isEmpty()) {
            System.err.println("queue is empty!");
            return -1;
        }
        // 最后一个元素的下标
        int index = tail == 0 ? data.length - 1 : tail - 1;
        return data[index];
    }

    public boolean isFull() {
        if ((tail + 1) % data.length == front)
            return true;
        return false;
    }

    public boolean isEmpty() {
        return tail == front;
    }

    public int getSize() {
        return size;
    }

    // 遍历循环队列
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("front [");
        // 取得最后一个元素的索引、
        int lastIndex = tail == 0 ? data.length - 1 : tail - 1;
        // 遍历循环队列
        for (int i = front; i != tail;) {
            sb.append(data[i]);
            if (i != lastIndex) {
                sb.append(",");
            }
            i = (i + 1) % data.length;
        }
        sb.append("] tail");
        return sb.toString();
    }
}
